/**	
*	Drawing an infinite open book : 

*/

import ij.ImagePlus;
import ij.plugin.PlugIn;
import ij.process.ColorProcessor;
import ij.process.ImageProcessor;

import java.awt.Color;
import java.awt.Polygon;
import java.io.PrintStream;
import java.util.Random;

public class LivreInfini1_ extends ImagePlus implements PlugIn {

	private PrintStream output; 
	private boolean windows=true; 
	private Random gene=new Random();
	

	public void run(String arg) {
		
		
		
		try{
			if(!windows)
			output=new PrintStream("/tmp/pages.txt");
			else
				output=new PrintStream("F:/Povray/pages.txt");
			}
			catch(Exception e){System.out.println("Probleme 1 "+e); System.exit(0);}
		
		
		
		
		ImageProcessor primeIP = new ColorProcessor(2000, 2000);
		int R=700; 
		int r=20; 
		int xa=1000-200,xb=1000-500,ya=1000-500,yb=1000-200;
		ya=ya+300; 
		yb=yb+300; 
		xa=xa+300; 
		xb=xb+300; 
		//int xa=1500,xb=500,ya=1500,yb=1800; 
		int abscisses[]={xa,xb,xb,xa}; 
		int ordonnees[]={ya,yb,yb-R,ya-R};
		
		primeIP.setLineWidth(3);
		
		Polygon background=new Polygon(new int[]{0,0,2000,2000},new int[]{0,2000,2000,0},4);
		primeIP.setColor(new Color(0.98f,0.98f,0.98f)); 
		primeIP.fillPolygon(background);
		
		double anglePerspective=Math.PI/8; 
		double perspective=Math.cos(anglePerspective*1.4);
		double angleOuverture=Math.PI/3-anglePerspective; 
		double rotation=angleOuverture+anglePerspective;
		
		
		double alpha=Math.PI/2; 
		int pas=50; 
		double pasAlpha=(Math.PI+0.1)/(1.34*pas);
		float red=0.9f; 
		float green=0.9f;
		float blue=0.9f;
		float cstPasColor=0.1f; 
		double pasColor;
	
		
		// La deuxieme de couverture
		R+=20; 
		primeIP.setColor(Color.BLUE); 
		abscisses[0]=(int)((xa-perspective*(r+10)*Math.sin(alpha-rotation)));
		abscisses[1]=(int)((xb-(r+10)*Math.sin(alpha-rotation)));
		abscisses[2]=(int)((xb-(R+10)*Math.sin(alpha-rotation))); 
		abscisses[3]=(int)((xa-perspective*(R+10)*Math.sin(alpha-rotation))); 
		
		ordonnees[0]=(int)((ya-perspective*r*Math.cos(alpha-rotation)));
		ordonnees[1]=(int)((yb-r*Math.cos(alpha-rotation)));		
		ordonnees[2]=(int)((yb-R*Math.cos(alpha-rotation))); 
		ordonnees[3]=(int)((ya-perspective*R*Math.cos(alpha-rotation)));
		
		Polygon pl=new Polygon(abscisses,ordonnees,4);
		primeIP.setColor(Color.BLUE); 
		primeIP.fillPolygon(pl); 
		
		R=R-20;
		abscisses[0]=(int)((xa-perspective*r*Math.sin(alpha-rotation)));
		abscisses[1]=(int)((xb-r*Math.sin(alpha-rotation)));
		abscisses[2]=(int)((xb-R*Math.sin(alpha-rotation))); 
		abscisses[3]=(int)((xa-perspective*R*Math.sin(alpha-rotation))); 
		
		ordonnees[0]=(int)((ya-perspective*r*Math.cos(alpha-rotation)));
		ordonnees[1]=(int)((yb-r*Math.cos(alpha-rotation)));		
		ordonnees[2]=(int)((yb-R*Math.cos(alpha-rotation))); 
		ordonnees[3]=(int)((ya-perspective*R*Math.cos(alpha-rotation)));
		
		pl=new Polygon(abscisses,ordonnees,4);
		primeIP.setColor(new Color(red,green,blue)); 
		primeIP.drawPolygon(pl); 
		primeIP.setColor(new Color(red,0,0)); 
		primeIP.fillPolygon(pl);
		
		/* PAGES DU COTE GAUCHE */
		int index0=2; 
		double cstAlpha0=Math.PI/6; 
		pasAlpha=cstAlpha0/(index0*index0+0.0);
		//for(int i=0;i<pas-2;i++)
		while((alpha-rotation>-Math.PI/4)&&(index0<400))
		{
			index0++; 
		pl=new Polygon(abscisses,ordonnees,4);
		primeIP.setColor(new Color(red,green,blue)); 
		primeIP.drawPolygon(pl); 
		primeIP.setColor(new Color(red,0,0)); 
		int ind=1+gene.nextInt(9); 
		output.println("object{pageR"+ind+"  rotate "+alpha/Math.PI*180+"*x}");
		primeIP.fillPolygon(pl);
			
		alpha=alpha-pasAlpha;
		pasAlpha=cstAlpha0/Math.pow(index0+0.0,1.25);
		pasColor=cstPasColor/Math.pow(index0+0.0,1.4); 
		abscisses[0]=(int)((xa-perspective*r*Math.sin(alpha-rotation)));
		abscisses[1]=(int)((xb-r*Math.sin(alpha-rotation)));
		abscisses[2]=(int)((xb-R*Math.sin(alpha-rotation))); 
		abscisses[3]=(int)((xa-perspective*R*Math.sin(alpha-rotation))); 
		
		ordonnees[0]=(int)((ya-perspective*r*Math.cos(alpha-rotation)));
		ordonnees[1]=(int)((yb-r*Math.cos(alpha-rotation)));		
		ordonnees[2]=(int)((yb-R*Math.cos(alpha-rotation))); 
		ordonnees[3]=(int)((ya-perspective*R*Math.cos(alpha-rotation)));
		red-=pasColor; 
		green-=pasColor;
		blue-=pasColor;			
		}
	

	
		
		red=0.9f; 
		blue=0.9f;
		green=0.9f;
		R+=30; 
		// La troisieme de couverture
		alpha=-(Math.PI/2); 
		abscisses[0]=(int)((xa-perspective*r*Math.sin(alpha-anglePerspective-0.05)));
		abscisses[1]=(int)((xb-r*Math.sin(alpha-anglePerspective-0.05)));
		abscisses[2]=(int)((xb-R*Math.sin(alpha-anglePerspective-0.05))); 
		abscisses[3]=(int)((xa-perspective*R*Math.sin(alpha-anglePerspective-0.05)));
		
		ordonnees[0]=(int)((ya-perspective*(r+30)*Math.cos(alpha-anglePerspective-0.05)));
		ordonnees[1]=(int)((yb-(r+30)*Math.cos(alpha-anglePerspective-0.05)));	
		ordonnees[2]=(int)((yb-(R+30)*Math.cos(alpha-anglePerspective-0.05))); 
		ordonnees[3]=(int)((ya-perspective*(R+30)*Math.cos(alpha-anglePerspective-0.05)));
		pl=new Polygon(abscisses,ordonnees,4);
		primeIP.setColor(Color.BLUE); 
		primeIP.fillPolygon(pl);
		
		/* PAGES DU COTE DROIT */
		
		R-=30;
		alpha=-(Math.PI/2); 
		abscisses[0]=(int)((xa-perspective*r*Math.sin(alpha-anglePerspective)));
		abscisses[1]=(int)((xb-r*Math.sin(alpha-anglePerspective)));
		abscisses[2]=(int)((xb-R*Math.sin(alpha-anglePerspective))); 
		abscisses[3]=(int)((xa-perspective*R*Math.sin(alpha-anglePerspective)));
		
		ordonnees[0]=(int)((ya-perspective*r*Math.cos(alpha-anglePerspective)));
		ordonnees[1]=(int)((yb-r*Math.cos(alpha-anglePerspective)));	
		ordonnees[2]=(int)((yb-R*Math.cos(alpha-anglePerspective))); 
		ordonnees[3]=(int)((ya-perspective*R*Math.cos(alpha-anglePerspective)));
		
		pas=pas/3;
		int index=2; 
		double cstAlpha=-Math.PI/6; 
		pasAlpha=cstAlpha/(index*index+0.0);
		pasColor=cstPasColor/Math.pow(index+0.0,1.4); 
		
		
		while((alpha-anglePerspective<-Math.PI/4)&&(index<1000))
		{
			index++;
			pl=new Polygon(abscisses,ordonnees,4);
			primeIP.setColor(new Color(red,green,blue)); 
			
			primeIP.drawPolygon(pl); 
			primeIP.setColor(new Color(red,0,0)); 
			 int ind=1+gene.nextInt(9); 
			output.println("object{page"+ind+"  rotate "+alpha/Math.PI*180+"*x}"); 
			primeIP.fillPolygon(pl);
			
			alpha=alpha-pasAlpha;
			pasAlpha=cstAlpha/Math.pow(index+0.0,1.25);
			pasColor=cstPasColor/Math.pow(index0+0.0,1.4); 
			abscisses[0]=(int)(xa-perspective*r*Math.sin(alpha-anglePerspective));
			abscisses[1]=(int)((xb-r*Math.sin(alpha-anglePerspective)));
			abscisses[2]=(int)((xb-R*Math.sin(alpha-anglePerspective))); 
			abscisses[3]=(int)((xa-perspective*R*Math.sin(alpha-anglePerspective))); 
			
			ordonnees[0]=(int)(ya-perspective*r*Math.cos(alpha-anglePerspective));
			ordonnees[1]=(int)((yb-r*Math.cos(alpha-anglePerspective)));	
			ordonnees[2]=(int)((yb-R*Math.cos(alpha-anglePerspective))); 
			ordonnees[3]=(int)((ya-perspective*R*Math.cos(alpha-anglePerspective)));
			red-=pasColor; 
			green-=pasColor;
			blue-=pasColor;
		}
		
		
		// Premiere de couverture
		R+=5;
		double epaisseur=20; 
		xb=xb+9; 
		yb=yb+9; 
		abscisses[0]= xb-r; 
		ordonnees[0]= yb-r;
		double l1=Math.sqrt(epaisseur*epaisseur); 

		abscisses[1]=(int)(xb-r-l1*Math.sin(rotation)); 
		ordonnees[1]=(int)(yb-r+l1*Math.cos(rotation));
		
		double l2=Math.sqrt(R*R+epaisseur*epaisseur);
		double theta=rotation-Math.atan(epaisseur/R); 
		abscisses[2]=(int)(xb-r-l2*Math.cos(theta)); 
		ordonnees[2]=(int)(yb-r-l2*Math.sin(theta));
		

		double l3=Math.sqrt(R*R); 
		abscisses[3]=(int)(xb-r-l3*Math.cos(rotation));
		ordonnees[3]=(int)(yb-r-l3*Math.sin(rotation));

		pl=new Polygon(abscisses,ordonnees,4);
		primeIP.setColor(Color.BLUE); 
		primeIP.fillPolygon(pl);
		
		
		// La derniere de couverture
		
		xb=xb-18; 
		yb=yb-18; 
		abscisses[0]= xb+r; 
		ordonnees[0]= yb+r;
		rotation=anglePerspective+0.05; 
		abscisses[1]=(int)(xb+r-l1*Math.sin(rotation)); 
		ordonnees[1]=(int)(yb+r+l1*Math.cos(rotation));
		
		//double l2=Math.sqrt(R*R+epaisseur*epaisseur);
		theta=rotation-Math.atan(epaisseur/R); 
		abscisses[3]=(int)(xb+r+l2*Math.cos(theta)); 
		ordonnees[3]=(int)(yb+r+l2*Math.sin(theta));
		

		//double l3=Math.sqrt(R*R); 
		abscisses[2]=(int)(xb+r+l3*Math.cos(rotation));
		ordonnees[2]=(int)(yb+r+l3*Math.sin(rotation));

		pl=new Polygon(abscisses,ordonnees,4);
		primeIP.setColor(Color.BLUE); 
		primeIP.fillPolygon(pl);
		
		
		setProcessor("Book in perspective", primeIP);
		output.close();
		show();
	}

	

}
